-
Notifications
You must be signed in to change notification settings - Fork 117
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Allow child one-to-one instances to be updated without providing PK #29
Conversation
Codecov Report
@@ Coverage Diff @@
## master #29 +/- ##
==========================================
+ Coverage 99.34% 99.35% +0.01%
==========================================
Files 3 3
Lines 153 156 +3
==========================================
+ Hits 152 155 +3
Misses 1 1
Continue to review full report at Codecov.
|
Thanks for the contribution. I'll review this PR on weekends. |
It seems you are trying to use an instance pk instead of a relation pk. What about cases, when we have |
@@ -115,6 +115,9 @@ def update_or_create_reverse_relations(self, instance, reverse_relations): | |||
if related_data is None: | |||
# Skip processing for empty data | |||
continue | |||
pk_name = field.Meta.model._meta.pk.attname | |||
if pk_name not in related_data: | |||
related_data[pk_name] = instance.pk |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
It seems the line related_data[pk_name] = instance.pk
should be replaced with something like that:
related_instance = getattr(instance, field_source, None)
if related_instance:
related_data[pk_name] = related_instance.pk
@@ -115,6 +115,9 @@ def update_or_create_reverse_relations(self, instance, reverse_relations): | |||
if related_data is None: | |||
# Skip processing for empty data | |||
continue | |||
pk_name = field.Meta.model._meta.pk.attname | |||
if pk_name not in related_data: |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
The related_data
can contain pk
attribute instead of pk_name which usually equals to id
@cjroth sorry to bother, but is still in a good state/up to date? I can give it a test if so! I'm getting some problems with the parent relationship not being created and believe this should fix it. EDIT: Tested it against this and I got a "field is required" error creating the parent: # models
class Competition(models.Model):
created_by = models.ForeignKey(settings.AUTH_USER_MODEL, null=True, blank=True, on_delete=models.SET_NULL, related_name="competitions")
created_when = models.DateTimeField(auto_now_add=True)
title = models.CharField(max_length=256)
class Page(models.Model):
competition = models.ForeignKey(Competition, related_name='pages', on_delete=models.DO_NOTHING)
title = models.TextField(max_length=255)
content = models.TextField()
index = models.PositiveIntegerField()
# Serializers
class PageSerializer(serializers.ModelSerializer): # also tried WriteableNestedModelSerializer here
# *NOTE* The competition property has to be replicated at the end of the file
# after the CompetitionSerializer class is declared
# competition = CompetitionSerializer(many=True)
class Meta:
model = Page
fields = (
'competition',
'title',
'content',
'index',
)
class CompetitionSerializer(WritableNestedModelSerializer):
created_by = serializers.SerializerMethodField(read_only=True)
pages = PageSerializer(many=True)
class Meta:
model = Competition
fields = (
'id',
'title',
'created_by',
'pages',
)
PageSerializer.competition = CompetitionSerializer(many=True) # also tried with explicit source definition Given: {
"title": "asdf",
"pages": [{"title": "test", "content": "test","index":"1"}]
} Result is: {
"pages": [
{
"competition": [
"This field is required."
]
}
]
} I could be doing something else stupid and/or misunderstanding this, as well... |
I haven't looked at it since this PR but we are using my branch with no issues at the moment. I will try to look at it when I get some time. Sorry to be MIA! |
So to anyone else who runs into my problem, I think I just misunderstood how class PageSerializer(WritableNestedModelSerializer):
class Meta:
model = Page
fields = (
'competition',
)
extra_kwargs = {
# This was key!
"competition": {"required": False}
} Thanks! |
I had a similar situation, where removing the field from The There's some perhaps inconsistent or unexpected behavior that we should write out in the docs. I'll try to do that shortly. On another note, is #29 ready to be merged? |
I think this MR contains something that can brake another part of logic. See my comments to this MR. |
This allows us to omit the pk when updating child one-to-one relations by inferring the pk from the parent when the child serializer is instantiated. Since a parent can only have one of a one-to-one child instance, it makes sense to assume which instance we mean to update.
Before:
After